package com.jamal2362.apktool.task;

import android.content.Context;
import android.content.DialogInterface;
import android.os.AsyncTask;
import androidx.appcompat.app.AlertDialog;
import brut.util.Logger;
import java.io.File;
import java.util.ArrayList;
import java.util.logging.Level;
import com.jamal2362.apktool.MainActivity;
import com.jamal2362.apktool.R;
import com.jamal2362.apktool.fragment.files.Refreshable;
import com.jamal2362.apktool.util.FileUtils;
import com.jamal2362.apktool.util.TextUtil;
import com.jamal2362.apktool.view.MessageView;

public abstract class AbstractTask extends AsyncTask<File, CharSequence, Boolean> implements Logger
{
	private Context ctx;
	private MessageView message;
	private AlertDialog dialog;
	private final Refreshable refresh;
	private File resultFile;
	private ArrayList<String> startLog;

	public AbstractTask(Context ctx, Refreshable refresh)
	{
		this.ctx = ctx;
		this.refresh = refresh;
		this.resultFile = null;
		this.startLog = new ArrayList<String>();
	}

	@Override
	protected Boolean doInBackground(File[] p1)
	{
		boolean success = true;
		for (File file : p1)
		{
			if (!process(file))
				success = false;
		}
		return Boolean.valueOf(success);
	}

	@Override
	protected void onPreExecute()
	{
		message = new MessageView(ctx);
		dialog = new AlertDialog.Builder(ctx).
			setView(message).
			setTitle(getTitle()).
			setCancelable(false).
			show();
	}
	

	protected abstract int getTitle();
	protected abstract boolean process(File f);

	@Override
	protected void onPostExecute(Boolean result)
	{
		dialog.dismiss();
		if (shouldShowFinishDialog() || !result)
		{
			final CharSequence text = message.getText();
			final ArrayList<String> arrText = message.getTextArray();
			final Context ctx = this.ctx;
			MessageView m = new MessageView(ctx);
			m.append(arrText);
			AlertDialog.Builder builder = new AlertDialog.Builder(ctx);
			builder.setView(m).
				setTitle(R.string.complete).
				setPositiveButton(R.string.ok, new DialogInterface.OnClickListener() {
					public void onClick(DialogInterface dialog, int id)
					{
						dialog.dismiss();
					}
				}).
				setNegativeButton(R.string.copy, new DialogInterface.OnClickListener() {
					public void onClick(DialogInterface dialog, int id)
					{
						TextUtil.setClipboard(ctx, text.toString());
						dialog.dismiss();
					}
				});
			if (resultFile != null)
			{
				int str = (resultFile.isDirectory() ? R.string.go_to : R.string.install);
				builder.setNeutralButton(str, new DialogInterface.OnClickListener() {
						public void onClick(DialogInterface dialog, int id)
						{
							if (resultFile.isDirectory())
							{
								if (refresh == null)
								{
									MainActivity ma = MainActivity.INSTANCE;
									if (ma != null)
										ma.showPath(resultFile);
									else
										TextUtil.st(ctx, ctx.getString(R.string.failed_open, resultFile.getAbsolutePath()));
								}
								else
								{
									refresh.refresh(resultFile);
								}
							}
							else
							{
								FileUtils.preInstall(ctx, resultFile);
							}
							dialog.dismiss();
						}
					});
			}
			builder.show();
		}
		if (refresh != null)
			refresh.refresh();
	}

	protected boolean shouldShowFinishDialog()
	{
		return true;
	}

	@Override
	protected void onProgressUpdate(CharSequence... values)
	{
		message.append(values[0]);
	}

	private String getText(int id, Object[] args)
	{
		return ctx.getResources().getString(id, args);
	}

	@Override
	public void info(int id, Object... args)
	{
		publishProgress(String.format("I: %s", getText(id, args)));
	}

	@Override
	public void warning(int id, Object... args)
	{
		publishProgress(String.format("W: %s", getText(id, args)));
	}

	@Override
	public void fine(int id, Object... args)
	{
		//publishProgress(String.format("F:%s\n",p0));
	}

	@Override
	public void text(int id, Object... args)
	{
		publishProgress(getText(id, args));
	}

	@Override
	public void error(int id, Object... args)
	{
		publishProgress(String.format("E: %s", getText(id, args)));
	}

	@Override
	public void log(Level level, String format, Throwable ex)
	{
		char ch = level.getName().charAt(0);
		String fmt = "%c: %s";
		publishProgress(String.format(fmt, ch, format));
		log(fmt, ch, ex);
	}

	private void log(String fmt, char ch, Throwable ex)
	{
		if (ex == null) return;
		publishProgress(String.format(fmt, ch, ex.getMessage()));
		for (StackTraceElement ste:ex.getStackTrace())
			publishProgress(String.format(fmt, ch, ste));
		log(fmt, ch, ex.getCause());
	}

	public Context getContext()
	{
		return this.ctx;
	}

	public void setResult(File f)
	{
		this.resultFile = f;
	}

	public void setResult(String f)
	{
		try
		{
			this.resultFile = new File(f);
		}
		catch (Exception e)
		{
			log(Level.SEVERE, "Result file failed", e);
		}
	}
}
